﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Songhay.Silverlight.BiggestBox.IndexPart.ViewModels
{
    using Models;
    using Songhay.Mvvm.ViewModels;
    using GalaSoft.MvvmLight.Messaging;

    /// <summary>
    /// Master-Detail data item
    /// </summary>
    public class MasterDetailDatumViewModel : TinyViewModelBase, IEditableObject
    {
        /// <summary>
        /// Gets or sets a value indicating whether this instance has nested items.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has nested items; otherwise, <c>false</c>.
        /// </value>
        [Display(AutoGenerateField = false)]
        public bool HasNestedItems
        {
            get { return this._hasNestedItems; }
            set
            {
                this._hasNestedItems = value;
                base.RaisePropertyChanged("HasNestedItems");
            }
        }
        /// <summary>
        /// Gets or sets a value indicating whether this instance is property zero.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is property zero; otherwise, <c>false</c>.
        /// </value>
        [Description("The mighty property of zero.")]
        [Display(Name = "Is True?", Order = 3)]
        public bool IsPropertyZero
        {
            get { return this._isPropertyZero; }
            set
            {
                this._isPropertyZero = value;
                base.RaisePropertyChanged("IsPropertyZero");
            }
        }

        /// <summary>
        /// Gets or sets the nested data items.
        /// </summary>
        /// <value>The nested data items.</value>
        [Display(AutoGenerateField = false)]
        public IEnumerable<MasterDetailDatumViewModel> NestedDataItems
        {
            get { return this._nestedDataItems; }
            set
            {
                this._nestedDataItems = value;
                base.RaisePropertyChanged("NestedDataItems");
                this.HasNestedItems = true;
            }
        }

        /// <summary>
        /// Gets or sets the primary key.
        /// </summary>
        /// <value>The primary key.</value>
        [Display(Name = "Primary Key", Order = 0)]
        [Key, Editable(false)]
        public int? PrimaryKey
        {
            get { return this.GetPrimaryKey(ref this._key); }
            set
            {
                this._key = value;
                base.RaisePropertyChanged("PrimaryKey");
            }
        }

        /// <summary>
        /// Gets or sets the property one.
        /// </summary>
        /// <value>The property one.</value>
        [Description("My special property of oneness.")]
        [Display(Name = "My Property", Order = 1)]
        public string PropertyOne
        {
            get { return this._propertyOne; }
            set
            {
                this._propertyOne = value;
                base.RaisePropertyChanged("PropertyOne");
            }
        }

        /// <summary>
        /// Gets or sets the property one date.
        /// </summary>
        /// <value>The property one date.</value>
        [Description("The date for my special property of unity.")]
        [Display(Name = "My Date", Order = 2)]
        [Required]
        public DateTime PropertyOneDate
        {
            get { return this.GetDateTime(ref this._propertyOneDate); }
            set
            {
                this._propertyOneDate = value;
                base.RaisePropertyChanged("PropertyOneDate");
            }
        }

        #region IEditableObject Members

        /// <summary>
        /// Causes the object to enter editing mode.
        /// </summary>
        public void BeginEdit()
        {
            this._cache = new MasterDetailDatumViewModel
            {
                PrimaryKey = this.PrimaryKey,
                IsPropertyZero = this.IsPropertyZero,
                PropertyOne = this.PropertyOne,
                PropertyOneDate = this.PropertyOneDate
            };
        }

        /// <summary>
        /// Causes the object to leave editing mode and revert to the previous, unedited value.
        /// </summary>
        public void CancelEdit()
        {
            this.IsPropertyZero = this._cache.IsPropertyZero;
            this.PropertyOne = this._cache.PropertyOne;
            this.PropertyOneDate = this._cache.PropertyOneDate;
        }

        /// <summary>
        /// Causes the object to leave editing mode and commit the edited value.
        /// </summary>
        public void EndEdit()
        {
            MasterDetailData.Update(this);
            this._cache = null;
        }

        #endregion

        DateTime GetDateTime(ref DateTime field)
        {
            if(field != default(DateTime)) return field;
            field = DateTime.Now;
            return field;
        }

        int? GetPrimaryKey(ref int? field)
        {
            if(field != null) return field;
            field = MasterDetailData.GetNextPrimaryKey();
            return field;
        }

        MasterDetailDatumViewModel _cache;

        bool _hasNestedItems;
        bool _isPropertyZero;
        int? _key;
        string _propertyOne;
        DateTime _propertyOneDate;
        IEnumerable<MasterDetailDatumViewModel> _nestedDataItems;
    }
}
